[NET] back: Fix netif rate limiting.
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Tue, 10 Oct 2006 12:47:09 +0000 (13:47 +0100)
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Tue, 10 Oct 2006 12:47:09 +0000 (13:47 +0100)
Signed-off-by: Keir Fraser <keir@xensource.com>
linux-2.6-xen-sparse/drivers/xen/netback/interface.c
linux-2.6-xen-sparse/drivers/xen/netback/netback.c

index 2785f4d895f1e537d9a2efa8bf2e4a3ebaaf8853..d70955fd1bb881168cc441af7f2cc80c365de34f 100644 (file)
@@ -153,6 +153,7 @@ netif_t *netif_alloc(domid_t domid, unsigned int handle, u8 be_mac[ETH_ALEN])
        netif->credit_bytes = netif->remaining_credit = ~0UL;
        netif->credit_usec  = 0UL;
        init_timer(&netif->credit_timeout);
+       netif->credit_timeout.expires = jiffies;
 
        dev->hard_start_xmit = netif_be_start_xmit;
        dev->get_stats       = netif_be_get_stats;
index 49f6013d445db5fa41e82af35bce61097e1afdde..f50577eb35831b59442a27b228d9f11a3b652f5a 100644 (file)
@@ -793,10 +793,27 @@ void netif_deschedule_work(netif_t *netif)
 }
 
 
+static void tx_add_credit(netif_t *netif)
+{
+       unsigned long max_burst;
+
+       /*
+        * Allow a burst big enough to transmit a jumbo packet of up to 128kB.
+        * Otherwise the interface can seize up due to insufficient credit.
+        */
+       max_burst = RING_GET_REQUEST(&netif->tx, netif->tx.req_cons)->size;
+       max_burst = min(max_burst, 131072UL);
+       max_burst = max(max_burst, netif->credit_bytes);
+
+       netif->remaining_credit = min(netif->remaining_credit +
+                                     netif->credit_bytes,
+                                     max_burst);
+}
+
 static void tx_credit_callback(unsigned long data)
 {
        netif_t *netif = (netif_t *)data;
-       netif->remaining_credit = netif->credit_bytes;
+       tx_add_credit(netif);
        netif_schedule_work(netif);
 }
 
@@ -1119,12 +1136,11 @@ static void net_tx_action(unsigned long unused)
                        /* Passed the point where we can replenish credit? */
                        if (time_after_eq(now, next_credit)) {
                                netif->credit_timeout.expires = now;
-                               netif->remaining_credit = netif->credit_bytes;
+                               tx_add_credit(netif);
                        }
 
                        /* Still too big to send right now? Set a callback. */
                        if (txreq.size > netif->remaining_credit) {
-                               netif->remaining_credit = 0;
                                netif->credit_timeout.data     =
                                        (unsigned long)netif;
                                netif->credit_timeout.function =